package com.xhwl.centiotdata.handler.account.impl;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.handler.account.AccountFactory;
import com.xhwl.centiotdata.handler.account.AccountHandler;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationFactory;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationHandler;
import com.xhwl.centiotdata.pojo.constant.HaiKangConstant;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.service.IOrgInfoService;
import com.xhwl.centiotdata.service.cent.IAccountCentService;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.suppliersystem.haikang.GeneralHaiKangHandler;
import com.xhwl.centiotdata.utils.FaceDataUtil;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.sdata.AccountDTO;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.auth.AuthAccountMapping;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.pojo.cent.iot.OrgInfo;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffDTO;
import com.xhwl.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author pengjunming
 * @description
 * @date 2022/7/5 10:31
 */
@Slf4j
@Service
public class AccountHaiKangHandler extends AccountHandler {

    @Resource
    private GeneralHaiKangHandler handler;

    @Resource
    private IAccountCentService iAccountCentService;

    @Resource
    private IAuthAccountCentService iAuthPedestrianCentService;

    @Resource
    private IOrgInfoService iOrgInfoService;

    @Override
    public void add(StaffDTO dto, Integer projectId, DeviceProjSupplierCategory integrationConfig) {
        handleAdd(dto, projectId, integrationConfig);
    }

    private void handleAdd(StaffDTO staffDTO, Integer projectId, DeviceProjSupplierCategory integrationConfig) {
        if (null != integrationConfig) {
            try {
                Map<String, Object> params = new HashMap<>();
                JSONObject properties = integrationConfig.getProperties();
                handleCommonInfo(staffDTO, params, integrationConfig.getProductId());
                String ipAndPort = properties.getString("ipAndPort");
                String ak = properties.getString("ak");
                String sk = properties.getString("sk");
                Integer productId = integrationConfig.getProductId();
                String tagId = properties.getString("tagId");

                if (StringUtils.isNotEmpty(staffDTO.getFaceUrl())) {
                    String image = FaceDataUtil.getFaceData(staffDTO.getFaceUrl());
                    Map<String, String> faceData = new HashMap<>();
                    faceData.put("faceData", image);
                    params.put("faces", Collections.singletonList(faceData));
                }
                JSONObject post = handler.post(HaiKangConstant.PERSON_ADD_URL, params, projectId, productId, ipAndPort,
                        ak, sk, tagId);
                log.info("添加人员信息:{}", post);
                String personId = post.getString("personId");
                String faceId = post.getString("faceId");
                //保存关联表

                boolean saveAuthResult = iAuthPedestrianCentService.save(projectId, staffDTO.getAccountId(), personId, null, integrationConfig.getProductId());

                log.info("账号关联关系保存结果 : {}", saveAuthResult);

                Account account = new Account();
                account.setId(staffDTO.getAccountId());
                //更新账户表人脸
                account.setFaceId(faceId);
                //密码改为空，否则会加密第二次
                account.setPassword(null);
                iAccountCentService.editAccountInfo(account);
            } catch (Exception e) {
                log.error("账号信息：{}", staffDTO);
                log.error("配置信息：{}", integrationConfig);
                log.error("同步海康平台异常", e);
            }
        }
    }

    /**
     * 随机证件号
     *
     * @return 证件号
     */
    private String getRandomCode() {
        Random random = new Random();
        char[] str = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
                'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
                'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
                'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

        int count = 0;
        StringBuffer buffer = new StringBuffer();
        while (count < 20) {
            int i = random.nextInt(62);
            buffer.append(str[i]);
            count++;
        }
        return buffer.toString();
    }

    @Override
    public void update(StaffDTO staffDTO, Integer projectId, DeviceProjSupplierCategory integrationConfig) {
        //查询关联表
        AuthAccountMapping authAccount = iAuthPedestrianCentService.query(projectId, staffDTO.getAccountId(), integrationConfig.getProductId());
        //没查到关联关系，则新增
        if (null == authAccount) {
            handleAdd(staffDTO, projectId, integrationConfig);
        } else {
            handleUpdate(staffDTO, projectId, integrationConfig, authAccount);
        }
    }

    private void handleUpdate(StaffDTO staffDTO, Integer projectId, DeviceProjSupplierCategory integrationConfig, AuthAccountMapping authAccount) {
        if (null != integrationConfig) {
            try {
                Map<String, Object> params = new HashMap<>();
                JSONObject properties = integrationConfig.getProperties();
                Account account = iAccountCentService.findById(staffDTO.getAccountId());
                handleCommonInfo(staffDTO, params, integrationConfig.getProductId());
                params.put("personId", authAccount.getOpenId());
                //更新人员信息
                String ipAndPort = properties.getString("ipAndPort");
                String ak = properties.getString("ak");
                String sk = properties.getString("sk");
                Integer productId = integrationConfig.getProductId();
                String tagId = properties.getString("tagId");

                handler.post(HaiKangConstant.PERSON_UPDATE_URL_V2, params, projectId, productId,
                        ipAndPort, ak, sk, tagId);

                if (StringUtils.isNotEmpty(staffDTO.getFaceUrl())) {
                    String image = FaceDataUtil.getFaceData(staffDTO.getFaceUrl());
                    //如果人脸ID不为空，则更新人脸数据
                    if (StringUtils.isNotEmpty(account.getFaceId())) {
                        Map<String, Object> updateFaceParams = new HashMap<>();
                        updateFaceParams.put("faceData", image);
                        updateFaceParams.put("faceId", account.getFaceId());
                        //更新人脸信息
                        handler.post(HaiKangConstant.PERSON_UDPATE_FACE_URL, updateFaceParams, projectId, productId,
                                ipAndPort, ak, sk, tagId);
                        //如果有授权，则更新权限信息
                    } else {
                        Map<String, Object> addFaceParams = new HashMap<>();
                        addFaceParams.put("faceData", image);
                        addFaceParams.put("personId", authAccount.getOpenId());
                        JSONObject post = handler.post(HaiKangConstant.FACE_ADD_URL, addFaceParams, projectId, productId,
                                ipAndPort, ak, sk, tagId);
                        //更新账户表人脸
                        account.setFaceId(post.getString("faceId"));
                        //密码改为空，否则会加密第二次
                        account.setPassword(null);
                        iAccountCentService.editAccountInfo(account);
                    }
                    ResultJson authorizedDevice = iAuthPedestrianCentService.getAuthorizedDevice(null, account.getId());
                    if (authorizedDevice.getState()) {
                        if (Objects.nonNull(authorizedDevice.getResult())) {
                            //更新人脸权限
                            PedestrianIntegrationConfigDTO configDTO = new PedestrianIntegrationConfigDTO();
                            configDTO.setProjectId(projectId);
                            configDTO.setProductId(productId);
                            configDTO.setIpAndPort(ipAndPort);
                            configDTO.setAk(ak);
                            configDTO.setSk(sk);
                            configDTO.setTagId(tagId);
                            List<DeviceDTO> list = JSONObject.parseArray(authorizedDevice.getResult().toString(), DeviceDTO.class);
                            List<String> thirdDevices = list.stream().map(DeviceDTO::getThirdDeviceId).collect(Collectors.toList());
                            if (CollectionUtils.isNotEmpty(thirdDevices)) {
                                PedestrianAuthDTO authDTO = new PedestrianAuthDTO();
                                authDTO.setUserOpenId(authAccount.getOpenId());
                                authDTO.setThirdDeviceIdList(thirdDevices);
                                PedestrianIntegrationHandler handler = PedestrianIntegrationFactory.getInvokeStrategy(productId);
                                log.info("人脸更新时，更新人脸权限:{}", JSONObject.toJSONString(authDTO));
                                handler.updateAuth(configDTO, authDTO);
                            }
                        }
                    }
                } else {
                    //删除人脸
                    Map<String, Object> deleteFace = new HashMap<>();
                    deleteFace.put("faceId", account.getFaceId());
                    handler.post(HaiKangConstant.FACE_DELETE_URL, deleteFace, projectId, productId, ipAndPort, ak, sk, tagId);

                    ResultJson authorizedDevice = iAuthPedestrianCentService.getAuthorizedDevice(null, account.getId());
                    if (authorizedDevice.getState()) {
                        if (Objects.nonNull(authorizedDevice.getResult())) {
                            //删除人脸权限
                            PedestrianIntegrationConfigDTO configDTO = new PedestrianIntegrationConfigDTO();
                            configDTO.setProjectId(projectId);
                            configDTO.setProductId(productId);
                            configDTO.setIpAndPort(ipAndPort);
                            configDTO.setAk(ak);
                            configDTO.setSk(sk);
                            configDTO.setTagId(tagId);
                            List<DeviceDTO> list = JSONObject.parseArray(authorizedDevice.getResult().toString(), DeviceDTO.class);
                            List<String> thirdDevices = list.stream().map(DeviceDTO::getThirdDeviceId).collect(Collectors.toList());
                            if (CollectionUtils.isNotEmpty(thirdDevices)) {
                                PedestrianAuthDTO authDTO = new PedestrianAuthDTO();
                                authDTO.setUserOpenId(authAccount.getOpenId());
                                authDTO.setDeletedThirdDeviceIdList(thirdDevices);
                                PedestrianIntegrationHandler handler = PedestrianIntegrationFactory.getInvokeStrategy(productId);
                                log.info("人脸删除时，删除人脸权限:{}", JSONObject.toJSONString(authDTO));
                                handler.deleteAuth(configDTO, authDTO);
                            }
                        }
                    }
                    //更新账户表人脸
                    account.setFaceId("");
                    //密码改为空，否则会加密第二次
                    account.setPassword(null);
                    iAccountCentService.editAccountInfo(account);
                }
            } catch (Exception e) {
                log.error("账号信息：{}", staffDTO);
                log.error("配置信息：{}", integrationConfig);
                log.error("同步更新海康平台异常", e);
            }
        }
    }

    private void handleCommonInfo(StaffDTO staffDTO, Map<String, Object> params, Integer productId) {
        if (CollectionUtils.isEmpty(staffDTO.getOrgIds())) {
            params.put("orgIndexCode", "root000000");
        } else {
            OrgInfo orgInfo = iOrgInfoService.getOrgInfo(staffDTO.getOrgIds().get(0), productId);
            if (Objects.isNull(orgInfo) || StringUtils.isEmpty(orgInfo.getOrgIndexCode())) {
                params.put("orgIndexCode", "root000000");
            } else {
                params.put("orgIndexCode", orgInfo.getOrgIndexCode());
            }
        }

        params.put("personName", staffDTO.getName());
        params.put("phoneNo", staffDTO.getPhone());
        params.put("email", staffDTO.getEmail());
        if (staffDTO.getSex() == 0) {
            params.put("gender", 2);
        } else if (staffDTO.getSex() == 1) {
            params.put("gender", 1);
        } else {
            params.put("gender", 0);
        }
        /*params.put("certificateNo", StringUtils.isEmpty(staffDTO.getPhone()) ? getRandomCode() : staffDTO.getPhone());
        params.put("certificateType", "990");*/
        // 默认是电话
        if (StringUtils.isEmpty(staffDTO.getCardNo())) {
            params.put("certificateNo", StringUtils.isEmpty(staffDTO.getPhone()) ? getRandomCode() : staffDTO.getPhone());
            params.put("certificateType", "990");
        } else {
            params.put("certificateNo", staffDTO.getIdCard());
            params.put("certificateType", "111");
        }
    }

    @Override
    public void delete(AccountDTO accountDTO, Integer projectId, DeviceProjSupplierCategory integrationConfig) {
        if (null != integrationConfig) {
            Map<String, Object> params = new HashMap<>();
            JSONObject properties = integrationConfig.getProperties();
            //查询关联表
            AuthAccountMapping authAccount = iAuthPedestrianCentService.query(projectId, accountDTO.getId(), integrationConfig.getProductId());
            if (null != authAccount) {
                params.put("personIds", Collections.singletonList(authAccount.getOpenId()));
                handler.post(HaiKangConstant.PERSON_DELETE_URL, params, projectId, integrationConfig.getProductId(),
                        properties.getString("ipAndPort"), properties.getString("ak"), properties.getString("sk"), properties.getString("tagId"));

                iAuthPedestrianCentService.deleteAccountMapping(projectId, accountDTO.getId(), authAccount.getOpenId(), integrationConfig.getProductId());
            }
        }

    }

    @Override
    public void afterPropertiesSet() {
        AccountFactory.register(ProductEnum.HAIKANG_ISC.getId(), this);
        log.info("海康账号管理注册成功");
    }
}
